import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;

public class Deck {

	private ArrayList<Card> cards;
	private ArrayList<Card> cardsInPlay;
	private ArrayList<Card> cardsToShuffle;

	public Deck() {
		/* get all allowed ranks for deck creation */
		ArrayList<String> ranks = Card.getAllowedRanks();
		/* get all allowed suites for deck creation */
		ArrayList<String> suites = Card.getAllowedSuites();
		/* start cards creation */
		this.cards = new ArrayList<Card>();
		for (String suit : suites) {
			for (String rank : ranks) {
				
				/* create a card */
				Card card = new Card(suit, rank);
				/* add created card into deck */
				this.addCard(card);
			}
		}
		/* there is no card in use once the deck is created */
		this.cardsInPlay = new ArrayList<Card>();
		/* there is no card to be shuffled once the deck is created */
		this.cardsToShuffle = new ArrayList<Card>();
	}
	
	void shuffle() {
		long seed = System.nanoTime();
		Collections.shuffle(cards, new Random(seed));
	}

	/**
	 * How many card do we have in full deck?
	 * 
	 * @return integer
	 */
	public int getTotalCards() {
		return this.cards.size();
	}

	/**
	 * How many card were played already?
	 * 
	 * @return integer
	 */
	public int getTotalCardsPlayed() {
		return this.cardsInPlay.size();
	}

	/**
	 * Add a card into a deck
	 * 
	 * @param card
	 */
	public void addCard(Card card) {
		this.cards.add(card);
	}

	/**
	 * Register a card played in the game, to avoid simple cheats
	 * 
	 * @param card
	 * @throws BadugiException
	 */
	public void addCardInPlay(Card card) throws BadugiException {
		if (!this.cardsInPlay.contains(card)) {
			this.cardsInPlay.add(card);
		} else {
			throw new BadugiException("Card " + card.toString()
					+ " is already in use.");
		}
	}

	/**
	 * If card will be played again, remove it from already played cards
	 * 
	 * @param card
	 * @throws BadugiException
	 */
	public void removeCardInPlay(Card card) throws BadugiException {
		if (this.cardsInPlay.contains(card)) {
			this.cardsInPlay.remove(card);
		} else {
			throw new BadugiException("Card " + card.toString()
					+ " were not in use yet.");
		}
	}

	/**
	 * Register a card which can be shuffled and reused
	 * 
	 * @param card
	 * @throws BadugiException
	 */
	public void addCardToShuffle(Card card) throws BadugiException {
		if (!this.cardsToShuffle.contains(card)) {
			this.cardsToShuffle.add(card);
		} else {
			throw new BadugiException("Card " + card.toString()
					+ " is already in use.");
		}
	}

	/**
	 * If card turns back to a player hand, remove it from cards to shuffle
	 * 
	 * @param card
	 * @throws BadugiException
	 */
	public void removeCardToShuffle(Card card) throws BadugiException {
		if (this.cardsToShuffle.contains(card)) {
			this.cardsToShuffle.remove(card);
		} else {
			throw new BadugiException("Card " + card.toString()
					+ " were not in use yet.");
		}
	}

	/**
	 * @return the cards
	 */
	public ArrayList<Card> getCards() {
		return cards;
	}

	/**
	 * @param cards
	 *            the cards to set
	 */
	public void setCards(ArrayList<Card> cards) {
		this.cards = cards;
	}

	/**
	 * @return the cardsInPlay
	 */
	public ArrayList<Card> getCardsInPlay() {
		return cardsInPlay;
	}

	/**
	 * @param cardsPlayed
	 *            the cardsInPlay to set
	 */
	public void setCardsInPlay(ArrayList<Card> cardsPlayed) {
		this.cardsInPlay = cardsPlayed;
	}

	/**
	 * @return the cardsToShuffle
	 */
	public ArrayList<Card> getCardsToShuffle() {
		return this.cardsToShuffle;
	}

	/**
	 * @param cardsToShuffle
	 *            the cardToShuffle to set
	 */
	public void setCardsToShuffle(ArrayList<Card> cardsToShuffle) {
		this.cardsToShuffle = cardsToShuffle;
	}

}
